package reading.util.utils;

import org.apache.commons.lang3.concurrent.BasicThreadFactory;

import java.util.concurrent.*;

/**
 * ${DESCRIPTION}
 * 线程池管理器
 *
 * @author txw
 * @create 2018-02-01 15:36
 **/
public class ExcutorsSchedulUtil {
    /**
     * cpu 使用比率
     */
    private static final double CPU_USE_RATE = 0.4;

    private static ThreadFactory threadFactory = new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build();
    public static ExecutorService threadPool = newCachedThreadPool();

    public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(), threadFactory, new ThreadPoolExecutor.AbortPolicy());
    }

    public static ExecutorService newSingleThreadPool() {
        return new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(), threadFactory, new ThreadPoolExecutor.AbortPolicy());
    }

    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<>(), threadFactory, new ThreadPoolExecutor.AbortPolicy());
    }

    public static ScheduledExecutorService newFixedThread(int nThreads) {
        return new ScheduledThreadPoolExecutor(nThreads,
                threadFactory);
    }

    public static void addRunnable(Runnable runnable) {
        threadPool.execute(runnable);
    }

    /**
     * 得到cpu个数
     *
     * @return
     */
    public static int getCpuNum() {
        return Runtime.getRuntime().availableProcessors();
    }

    /**
     * 阿姆达尔定律
     * 最佳线程池优化个数：cpu个数 *  cpu 使用率  *(1+ (等待时间)/(计算时间))
     *
     * @return
     */
    public static int getThreadSNum() {
        double sum = getCpuNum() * CPU_USE_RATE * (1 + 14 / 13);
        return (int) (sum);
    }
}
